package down.sallai.ml.controller;


import down.sallai.ml.services.DownFile;
import down.sallai.ml.util.Constants;
import down.sallai.ml.util.HttpsDownUtils;
import down.sallai.ml.util.R;
import down.sallai.ml.util.VerityCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.HashMap;

@RestController
@Slf4j
public class Download {
    @Value("${mydown.fileLocal}")
    String fileLocal;
    @Autowired
    DownFile downFile;


    @PostMapping("/download")
    public String downLoad(String url,String verityCode, HttpServletRequest request) {
//       示例链接 https://github.com/sallai1/java/archive/master.zip

// 验证验证吗
        if(Constants.Down.DOWN_SERVER_STATE.equals("false")) return new R().setMsg("下载服务已被管理员暂停！").setCode(303).toString();

        HttpSession session = request.getSession();
        session.setAttribute("down",null);
        String code = (String)session.getAttribute("verityCode");
        log.info("传入->"+verityCode);
        log.info("待验证->"+code);
        String flag = "https://github.com";
        url = url.trim();
        if(null==code||!verityCode.equalsIgnoreCase(code)){
           return new R().setCode(303).setMsg("验证码错误").toString();
        }
        if(url.indexOf(flag)!=0) return new R().setCode(300).setMsg("链接格式不正确，只能下载github项目").toString();
        request.getSession().setAttribute("verityCode",null);   //验证完销毁
        String localhost =  request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort();


        String res = null;
        try {
            res = new HttpsDownUtils().downloadFile(url, fileLocal, request);
        } catch (SocketTimeoutException e) {
            e.printStackTrace();
            return new R().setCode(201).setMsg("连接超时").toString();
        }catch(Exception e){
            e.printStackTrace();
            return new R().setCode(201).setMsg("出现异常").toString();
        }
        HashMap<String, String> stringStringHashMap = new HashMap<>();
        stringStringHashMap.put("fileName","/download/file?fileName="+res);
        System.out.println("存储路径->"+fileLocal);
        return new R().setCode(200).setMsg("下载已完成！").setData(stringStringHashMap).toString();
    }

    @GetMapping("/download/file")
    public void downLoad(String fileName,HttpServletRequest request,HttpServletResponse response){
        FileInputStream in=null;
        response.setContentType("application/zip");
        response.setHeader("Content-Disposition","attachment;filename="+fileName);
        response.setHeader("Accept-Ranges","bytes");
        long start = 0;
        long end = -1;
        //查看头是否包含分片下载
        String range = request.getHeader("Range");

        ServletOutputStream outputStream = null;

        try {
            File file = new File(fileLocal + fileName);
            in = new FileInputStream(file);
            if(null != range && !("".equals(range))) {
                log.info("range:"+range);
                String[] strs  = range.replace("bytes=","").split("-");
                start = Long.parseLong(strs[0]);
                if(strs.length == 1 || strs[1].equals("")) {
                    end = file.length();
                }else{
                    end = Long.valueOf(strs[1]);
                }
                response.setHeader("Content-Length",String.valueOf(end-start+1));
                response.setHeader("Content-Range","bytes "+start+"-"+end+"/"+file.length());
                response.setStatus(206);
            }else{
                log.info("not have a range info");
                end = file.length();
                response.setHeader("Content-Length",String.valueOf(file.length()));
            }


            log.info("start->"+start+" end->"+end);
            in.skip(start);
            outputStream = response.getOutputStream();
            long sum = 0;
            int len = 0;
            byte[] buffer = new byte[1024*3];
            while(sum <= end && (len=in.read(buffer))>0){
                outputStream.write(buffer,0,len);
                sum+=len;
            }
        } catch (FileNotFoundException e) {

        } catch (IOException e) {

        }finally {
            log.info("关闭连接");
            try {
                if ( in != null) {
                    in.close();
                    in = null;
                }
                if( null != outputStream ) {
                    outputStream.close();
                }
            } catch (IOException e) {
            }
        }
    }

    @GetMapping({"/img"})
    public void  verityCode(HttpServletResponse response, HttpServletRequest request){
        VerityCode verityCode = new VerityCode();
        try {
            verityCode.verifyCode(request,response);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    @GetMapping({"/download/process"})
    public String  getProcess(HttpServletRequest request){
        Object o = request.getSession().getAttribute("downProcess");
        if(null==o)  return new R().setMsg("当前没有下载信息").setCode(300).toString();
        String down = (String)o;
        System.out.println("下载进度"+down);
        return new R().setMsg(down).setCode(200).setData(down).toString();

    }


}
